import threading
import asyncio
from nonebot.adapters import Bot

BotRecv = None


class BotTaskThread(threading.Thread):
    def __init__(self, bot_loop):
        super(BotTaskThread, self).__init__()
        self.__bot_loop = bot_loop

    def run(self) -> None:
        self.__bot_loop.start()


class BotLoop:
    def __init__(self, bot: Bot, loop):
        self.__loop = loop
        self.__bot = bot

    def start(self):
        asyncio.set_event_loop(self.__loop)
        print("bot server: start loop")
        self.__loop.run_forever()

    def stop(self):
        print("bot server: stop loop")
        self.__loop.stop()

    def __msg_to_client(self, msg):
        if len(msg) == 4:
            conn_type, conn_id, qq_id, msg_str = msg
            if conn_type == "group":
                at_str = "[CQ:at,qq=%s]\r\n" % qq_id
                self.__bot.send_msg(group_id=conn_id, message="".join((at_str, msg_str)))
            elif conn_type == "private":
                self.__bot.send_msg(user_id=conn_id, message=msg_str)
            else:
                pass
        return True

    def __disconnect(self):
        self.stop()
        return True

    def run_task(self, command, msg=""):
        print("bot server: command is ", command)
        if command == 'send_to_client':
            asyncio.run_coroutine_threadsafe(self.__msg_to_client(msg), self.__loop)
        elif command == 'disconnect':
            asyncio.run_coroutine_threadsafe(self.__disconnect(), self.__loop)
        else:
            pass
        return True


def bot_recv_init(bot: Bot):
    global BotRecv
    thread_loop = asyncio.new_event_loop()
    BotRecv = BotLoop(bot, thread_loop)
    BotTaskThread(BotRecv).start()


def bot_recv_disconnect():
    global BotRecv
    if BotRecv is not None:
        BotRecv.run_task('disconnect')
    del BotRecv


def bot_recv(conn_type, conn_id, qq_id, msg):
    global BotRecv
    if BotRecv is not None:
        BotRecv.run_task('send_to_client', (conn_type, conn_id, qq_id, msg))
    return True
